package JVM;

public class jvm4 {

    /**
     * 5.2Parallel GC
     *  Parallel GC是Serial GC的多线程版本,设计目标是高吞吐量,即在单位时间内完成更多的工作。它通过
     *  利用多个GC线程并行处理垃圾回收,减少单词GC的耗时,但在可达性分析和整理内存碎片都会出现STW
     *  新生代的回收 采用 标记-复制算法
     *  老年代的回收 采用 标记-整理算法
     *
     */

    /**
     * 5.3 并发的可达性分析
     *   在讲解CMS垃圾收集器之前,先讲解一下并发的可达性分析,即在垃圾收集过程中,多个线程可以同时进行可达性分析,
     *   这意味着必须全程冻结用户线程的运行。如果无法保证一致性会出现两种情况
     *    1.原本消亡的对象错误标记为存活
     *    2.原本存活的对象错误标记为已消亡。
     *    这两种情况,第一种一般是可容忍的,无非就是下次垃圾收集的时候再把他回收掉,但是对于第二种是不可接受的,因为它
     *    会使程序发生错误。我们把第二种情况称之为对象消失。
     */

    /**
     * 5.4CMS
     *  CMS GC设计目标是最小化停顿时间,通过并发技术让GC线程与应用线程同时运行。主要针对老年代，而新生代通常搭配其他收集器。
     *  CMS Old采用标记-清除算法,但是它实现上有所不同,主要体现在可达性分析和清除上不可达对象上。正常的可达性分析中的标记
     *  所有GC Roots和通过GC Roots查找可达对象都会STW。但是CMS只有在标记所有GC Roots的时候STW,对于通过GC Roots查找
     *  可达对象采用用户线程并发执行,不会STW,然后进行重新标记的时候STW一会,最后就是并发清除了。这里采用到的就是增量更新来确保
     *  并发的可达性分析的正确性。
     *  1.初始化标记
     *  2.并发标记
     *  3.重新标记
     *  4.并发清除
     *
     *  CMS收集器无法处理浮动垃圾
     *   因为垃圾收集线程和用户线程是并发的,所以不能在内存彻底或将要满时才进行垃圾收集。如果在CMS运行期间,给大对象分配内存时内存不足的话，
     *   会冻结用户线程的执行,临时启用SerialOld收集器来重新进行老年代的垃圾收集。
     *   如果老年代内存充足,但是就是无法给大对象分配内存或晋升的对象始终无法分配到合适的内存,那么会使用Serial提前进行一次
     *   Full GC(对老年代和新生代都进行垃圾收集)。为什么内存充足,还无法分配？
     *   CMS采用的是标记-清除算法,而标记清除算法会导致内存碎片化。
     *
     *  5.5 G1 GC(Garbage-First GC)
     *  G1垃圾收集器是Java虚拟机(JVM)提供的一种现代垃圾收集器(Java9后默认的垃圾收集器),设计目标是低停时间和高吞吐量的
     *  平衡,特别适合大堆内存和多核处理器环境。我们可以通过设置期望的停顿时间,G1回收器会在你期望的停顿时间里优先回收垃圾最多
     *  的区域
     *
     *  与之前的垃圾收集器不同,G1将堆划分为多个大小相等的Region(默认2048个,大小范围为1MB到32MB,由堆大小动态调整)。每个Region
     *  可以是：Eden Survivor Old Humongous(存放超大对象,超过region一半大的),Free(空间区域,尚未分配角色)。
     *  G1的回收分为Minor GC(新生代回收)和Mixed GC(混合回收),并在必要时触发Full GC
     *  1.新生代回收 采用标记-复制算法,将存活对象复制到新的Survivor区,然后清理掉Survivor区中存活对象,Survivor区满时进行
     *  2.并发标记：这里的并发标记是独立于新生代和混合回收的,当老年代的内存不足时,在进行新生代回收的STW时,G1会扫描所有的GC Roots
     *  然后在STW结束后,并发的执行可达性分析,同时采用原始快照的方法避免对象消失。
     *  3.混合回收采用 标记-整理算法,并发标记后一般会直接进入混合回收,进入stw阶段,进行新生代的回收和部分老年代的回收(新生代和老年代
     *  的回收都是基于前面并发标记是结果,其中老年代的回收只回收部分有价值的region,如果距离前面并发结果时间过长,可以重新并发标记)
     *  清除部分老年代中的无用对象。
     */
}
